package org.ciallo.easytokencore.interceptor;

import org.ciallo.easytokencore.config.ContextInterceptorConfig;
import org.ciallo.easytokencore.context.EasyContextHolder;
import org.ciallo.easytokencore.context.model.EasyCookie;
import org.ciallo.easytokencore.context.model.EasyRequest;
import org.ciallo.easytokencore.context.model.EasyResponse;
import org.ciallo.easytokencore.context.model.EasyToken;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 请求上下文拦截器
 *
 * <p>核心功能：</p>
 * <ul>
 *   <li>在请求处理前注入Request/Response上下文</li>
 *   <li>在请求处理后清理上下文</li>
 *   <li>确保线程安全的上下文访问</li>
 * </ul>
 *
 * <p>执行流程：</p>
 * <ol>
 *   <li>preHandle: 初始化请求上下文</li>
 *   <li>业务处理: 通过EasyContextHolder访问上下文</li>
 *   <li>afterCompletion: 清理上下文</li>
 * </ol>
 *
 * <p>注意事项：</p>
 * <ul>
 *   <li>必须确保afterCompletion执行清理操作</li>
 *   <li>上下文仅限当前请求线程使用</li>
 *   <li>拦截器优先级应设为最高</li>
 * </ul>
 *
 * @Description: 请求上下文拦截器
 * @Author: Jukomu
 * @Package: org.ciallo.easytokencore.interceptor
 * @Project: easy-token-demo
 * @Version: 1.0.0
 * @name: EasyContextInterceptor
 * @Date: 2025-05-06
 * @Filename: EasyContextInterceptor
 * @see EasyContextHolder
 * @see ContextInterceptorConfig
 */
@Component
public class EasyContextInterceptor implements HandlerInterceptor {
    /**
     * 在所有业务逻辑前执行，注入上下文
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        // 将当前请求的 Request/Response 存入上下文持有类
        String authorization = request.getHeader("Authorization");
        EasyContextHolder.setContext(new EasyCookie(), new EasyRequest(request), new EasyResponse(response), new EasyToken(authorization));
        return true;
    }

    /**
     * 请求结束后清理上下文
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        EasyContextHolder.clear(); // 必须清理，避免内存泄漏
    }
}
